#ifndef KINECTSENSOR_H
#define KINECTSENSOR_H

// Windows Header Files
#include <windows.h>

#include <Shlobj.h>


// Kinect Header files
#include <Kinect.h>

#include <QObject>
#include <QString>
#include <QMouseEvent>
#include <QGuiApplication>
#include <QWidget>
#include <QPoint>
#include <QDebug>
#include <QWindow>
#include <QCursor>
#include <QBitmap>
#include <QTimer>
#include <QMouseEvent>
#include <QGuiApplication>
#include <QPoint>

enum mouseState{
    mouseState_no_state=0,
    mouseState_pressing=1,
    mouseState_released=2,
    mosueState_isdragging=3
};

class KinectSensor : public QObject
{
    Q_OBJECT
public:
    //properties cursor
    Q_PROPERTY(int cursorx READ cursorx WRITE setCursorx NOTIFY cursorxChanged)
    Q_PROPERTY(int cursory READ cursory WRITE setCursory NOTIFY cursoryChanged)
    //properties hands's states
    Q_PROPERTY(int leftHandState READ leftHandState NOTIFY leftHandStateChanged)
    Q_PROPERTY(int rightHandState READ rightHandState NOTIFY rightHandStateChanged)
    //properties right hand position
    Q_PROPERTY(double rightHandX READ rightHandX NOTIFY rightHandXChanged)
    Q_PROPERTY(double rightHandY READ rightHandY NOTIFY rightHandYChanged)

    //properties left hand position
    Q_PROPERTY(double leftHandZ READ leftHandZ NOTIFY leftHandZChanged)
    Q_PROPERTY(double leftHandX READ leftHandX NOTIFY leftHandXChanged)
    Q_PROPERTY(double leftHandY READ leftHandY NOTIFY leftHandYChanged)

    //hand's coordinate position
    Q_PROPERTY(int leftHandCoordX READ leftHandCoordX NOTIFY leftHandCoordXChanged)
    Q_PROPERTY(int leftHandCoordY READ leftHandCoordY NOTIFY leftHandCoordYChanged)
    Q_PROPERTY(int rightHandCoordX READ rightHandCoordX NOTIFY rightHandCoordXChanged)
    Q_PROPERTY(int rightHandCoordY READ rightHandCoordY NOTIFY rightHandCoordYChanged)

    int cursorx(){
        return cursor->pos().x();
    }
    int cursory(){
        return cursor->pos().y();
    }
    void setCursorx(int x){
        cursor->setPos(x,cursor->pos().y());
        cursorxChanged();

    }
    void setCursory(int y){
        cursor->setPos(cursor->pos().x(),y);
        cursoryChanged();
    }

    int leftHandState(){

        /**0:未知状态
          *1：张开手
          * 2：闭合手
          * 3：剪刀手
          * 4：没有跟踪到
            **/
        if(mleftHandState==HandState_Unknown){
            return 0;
        }
        else if(mleftHandState==HandState_Open){
            return 1;
        }
        else if(mleftHandState==HandState_Closed){
            return 2;
        }
        else if(mleftHandState==HandState_Lasso){
            return 3;
        }
        else if(mleftHandState==HandState_NotTracked){
            return 4;
        }
    }
    int rightHandState(){
        /**0:未知状态
          *1：张开手
          * 2：闭合手
          * 3：剪刀手
          * 4：没有跟踪到
            **/
        if(mrightHandState==HandState_Unknown){
            return 0;
        }
        else if(mrightHandState==HandState_Open){
            return 1;
        }
        else if(mrightHandState==HandState_Closed){
            return 2;
        }
        else if(mrightHandState==HandState_Lasso){
            return 3;
        }
        else if(mrightHandState==HandState_NotTracked){
            return 4;
        }
    }

    double rightHandX(){
        return rightHandJoint.Position.X;
    }
    double rightHandY(){
        return rightHandJoint.Position.Y;
    }

    int leftHandCoordX(){
        return leftHandPoint.X;
    }
    int leftHandCoordY(){
        return leftHandPoint.Y;
    }
    int rightHandCoordX(){
        return rightHandPoint.X;
    }
    int rightHandCoordY(){
        return rightHandPoint.Y;
    }
    double leftHandZ(){
        return leftHandJoint.Position.Z;
    }
    double leftHandX(){
        return leftHandJoint.Position.X;
    }
    double leftHandY(){
        return leftHandJoint.Position.Y;
    }


    explicit KinectSensor(QObject *parent = 0);

    //initialize default sensor
    Q_INVOKABLE HRESULT InitializeDefaultSensor();

    //update body anything
    Q_INVOKABLE void updatebody();

    //track body
    Q_INVOKABLE bool hasTrackingBody();

    //hand position mapping
    Q_INVOKABLE  void mapJointsToXYCoord();


    signals:
    void cursorxChanged();
    void cursoryChanged();
    void leftHandStateChanged();
    void rightHandStateChanged();
    void rightHandXChanged();
    void rightHandYChanged();

    void leftHandCoordXChanged();
    void leftHandCoordYChanged();
    void rightHandCoordXChanged();
    void rightHandCoordYChanged();
    void leftHandZChanged();
    void leftHandXChanged();
    void leftHandYChanged();

private:
    //handle mouse event
    void sendMouseLeftPressEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
        QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        QGuiApplication::sendEvent(QGuiApplication::focusWindow(),mevent);
        delete mevent;
    }
    void sendMouseLeftReleaseEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
        QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        QGuiApplication::sendEvent(QGuiApplication::focusWindow(),mevent);
        delete mevent;
    }
    void sendMouseDragEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
         QMouseEvent *mevent=new QMouseEvent(QEvent::DragMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
         QGuiApplication::sendEvent(QGuiApplication::focusWindow(),mevent);
         delete mevent;
    }
    void seedMouseLeftClickEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
         QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonDblClick, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
         QGuiApplication::sendEvent(QGuiApplication::focusWindow(),mevent);
         delete mevent;
    }

    // Current Kinect
    IKinectSensor*          m_pKinectSensor;
    ICoordinateMapper*      m_pCoordinateMapper;

    IBody *currentPBody;

    //hand state
    HandState mleftHandState=HandState_Unknown;
    HandState mrightHandState=HandState_Unknown;

    //hand joint (get both hands's position)
    Joint leftHandJoint;
    Joint rightHandJoint;

    // Body reader
    IBodyFrameReader*       m_pBodyFrameReader;

    //handle cursor
    QCursor *cursor;
    //hand's coordinate position
    ColorSpacePoint leftHandPoint;
    ColorSpacePoint rightHandPoint;

    //handle update timer
    QTimer *mTimer;

    //current event state event
    /**
     * 0:null
     * 1:pressed
     * 2:released
     * 3:draging
     * */
    mouseState currentMouseState;


    //get currentBody
    bool getCurrentBody(IBody **ppbodies);

    //get body joint
    void getBodyJoint();


signals:

public slots:
    void upDateKinect();
    void closeKinect();
};


#endif // KINECTSENSOR_H
